import { SQLStatement, DatabaseDialect } from './Parser';
import { ICompatibleAdapter, ProtocolType } from '../core/interfaces';

export interface DatabaseAdapter extends ICompatibleAdapter {
    executeQuery(sql: string): Promise<any[]>;
    executeUpdate(sql: string): Promise<number>;
}

export interface RoutingStrategy {
    route(stmt: SQLStatement): DatabaseAdapter[];
}

export class ShardByTableStrategy implements RoutingStrategy {
    constructor(private adapters: DatabaseAdapter[]) {}

    route(stmt: SQLStatement): DatabaseAdapter[] {
        if (stmt.tables.length === 0) return [];
        
        // 简单按表名路由
        const table = stmt.tables[0];
        const adapterIndex = table.charCodeAt(0) % this.adapters.length;
        return [this.adapters[adapterIndex]];
    }
}

export class ResultMerger {
    static merge(results: any[][]): any[] {
        // 简单合并结果集
        return results.flat();
    }

    static mergeWithOrder(results: any[][], orderBy: string): any[] {
        // 带排序的合并
        const merged = this.merge(results);
        return merged.sort((a, b) => {
            if (a[orderBy] < b[orderBy]) return -1;
            if (a[orderBy] > b[orderBy]) return 1;
            return 0;
        });
    }
}

export class DatabaseMiddleware {
    private dialect: DatabaseDialect;
    private routingStrategy: RoutingStrategy;

    constructor(
        private adapters: DatabaseAdapter[],
        dialect: DatabaseDialect,
        strategy: RoutingStrategy
    ) {
        this.dialect = dialect;
        this.routingStrategy = strategy;
    }

    async execute(sql: string): Promise<any> {
        const stmt = SQLParser.parse(sql);
        const targetAdapters = this.routingStrategy.route(stmt);

        if (targetAdapters.length === 0) {
            throw new Error('No suitable database adapter found');
        }

        // 转换SQL方言
        const convertedSQL = this.convertSQL(stmt);

        if (stmt.type === 'SELECT') {
            const results = await Promise.all(
                targetAdapters.map(adapter => adapter.executeQuery(convertedSQL))
            );
            return ResultMerger.merge(results);
        } else {
            const results = await Promise.all(
                targetAdapters.map(adapter => adapter.executeUpdate(convertedSQL))
            );
            return results.reduce((sum, count) => sum + count, 0);
        }
    }

    private convertSQL(stmt: SQLStatement): string {
        // 实际实现应更完整
        let sql = `${stmt.type} ${stmt.columns.join(', ')} FROM ${stmt.tables.join(', ')}`;
        
        if (stmt.conditions.length > 0) {
            sql += ` WHERE ${stmt.conditions.join(' AND ')}`;
        }

        if (stmt.limit !== undefined) {
            sql += ' ' + this.dialect.convertLimit(stmt.limit, stmt.offset);
        }

        return sql;
    }
}